package cn.buk.qms.web;

import cn.buk.tms.dto.*;
import cn.buk.tms.entity.order.flight.FlightRefundOrder;
import cn.buk.qms.service.ReportService;
import cn.buk.common.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/report")
public class ReportController extends BaseController {

    private final ReportService service;

    @Autowired
    public ReportController(ReportService reportService) {
        this.service = reportService;
    }

    /**
     * 出票月报
     */
    @RequestMapping("/monthly/sale")
    public List<ReportFlightTicketDto> searchFlightTicketMonthly(HttpServletRequest request,
                                                                 @RequestParam("beginDate") Date beginDate,
                                                                 @RequestParam("endDate") Date endDate,
                                                                 @RequestParam(value = "supplierId", defaultValue = "0") int supplierId,
                                                                 @RequestParam(value = "customerId", defaultValue = "-1") int customerId,
                                                                 @RequestParam(value = "op1", defaultValue = "0") int op1
                                                                 ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        final String username = getUsername(request);
        if (op1 <= 0) {
            // 查询公司的月报
            return service.searchFlightMonthlySale(enterpriseId, userId, beginDate, endDate, supplierId, customerId);
        } else {
            // op1 > 0 表示查询当前用户的月报
            return service.searchFlightMonthlySale(enterpriseId, username, beginDate, endDate, supplierId, customerId);
        }
    }

    /**
     * 退票月报(账单）
     */
    @RequestMapping("/monthly/refund")
    public List<ReportFlightRefundDto> searchFlightRefundMonthly(HttpServletRequest request,
                                                                 @RequestParam("beginDate") Date beginDate,
                                                                 @RequestParam("endDate") Date endDate,
                                                                 @RequestParam(value = "supplierId", defaultValue = "0") int supplierId,
                                                                 @RequestParam(value = "customerId", defaultValue = "-1") int customerId,
                                                                 @RequestParam(value = "op1", defaultValue = "0") int op1) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        final String username = getUsername(request);
        if (op1 <= 0) {
            // 查询公司的月报
            return service.searchFlightRefundMonthly(enterpriseId, userId, beginDate, endDate, supplierId, customerId);
        } else {
            return service.searchFlightRefundMonthly(enterpriseId, username, beginDate, endDate, supplierId, customerId);
        }
    }

    /**
     * 改签月报(账单）
     */
    @RequestMapping("/monthly/change")
    public List<ReportFlightChangeDto> searchFlightChangeMonthly(HttpServletRequest request,
                                                                 @RequestParam("beginDate") Date beginDate,
                                                                 @RequestParam("endDate") Date endDate,
                                                                 @RequestParam(value = "supplierId", defaultValue = "0") int supplierId,
                                                                 @RequestParam(value = "customerId", defaultValue = "-1") int customerId,
                                                                 @RequestParam(value = "op1", defaultValue = "0") int op1) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        final String username = getUsername(request);
        if (op1 <= 0) {
            // 查询公司的月报
            return service.searchFlightChangeMonthly(enterpriseId, userId, beginDate, endDate, supplierId, customerId);
        } else {
            return service.searchFlightChangeMonthly(enterpriseId, username, beginDate, endDate, supplierId, customerId);
        }
    }

    /**
     * vas月报(账单）
     */
    @RequestMapping("/monthly/vas")
    public List<ReportVasDto> searchVasMonthly(HttpServletRequest request,
                                               @RequestParam("beginDate") Date beginDate,
                                               @RequestParam("endDate") Date endDate,
                                               @RequestParam(value = "supplierId", defaultValue = "0") int supplierId,
                                               @RequestParam(value = "customerId", defaultValue = "-1") int customerId,
                                               @RequestParam(value = "op1", defaultValue = "0") int op1) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        final String username = getUsername(request);
        if (op1 <= 0) {
            // 查询公司的月报
            return service.searchVasMonthly(enterpriseId, userId, beginDate, endDate, supplierId, customerId);
        } else {
            return service.searchVasMonthly(enterpriseId, username, beginDate, endDate, supplierId, customerId);
        }
    }

    /**
     * 酒店月报(账单）
     */
    @RequestMapping("/monthly/hotel")
    public List<ReportHotelDto> searchHotelMonthly(HttpServletRequest request,
                                                   @RequestParam("beginDate") Date beginDate,
                                                   @RequestParam("endDate") Date endDate,
                                                   @RequestParam(value = "supplierId", defaultValue = "0") int supplierId,
                                                   @RequestParam(value = "customerId", defaultValue = "-1") int customerId,
                                                   @RequestParam(value = "op1", defaultValue = "0") int op1) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        final String username = getUsername(request);
        if (op1 <= 0) {
            // 查询公司的月报
            return service.searchHotelMonthly(enterpriseId, userId, beginDate, endDate, supplierId, customerId);
        } else {
            return service.searchHotelMonthly(enterpriseId, username, beginDate, endDate, supplierId, customerId);
        }
    }

    /**
     * 火车票月报(账单）
     */
    @RequestMapping("/monthly/train")
    public List<ReportTrainDto> searchTrainMonthly(HttpServletRequest request,
                                                 @RequestParam("beginDate") Date beginDate,
                                                 @RequestParam("endDate") Date endDate,
                                                 @RequestParam(value = "supplierId", defaultValue = "0") int supplierId,
                                                 @RequestParam(value = "customerId", defaultValue = "-1") int customerId,
                                                   @RequestParam(value = "op1", defaultValue = "0") int op1) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        final String username = getUsername(request);
        if (op1 <= 0) {
            // 查询公司的月报
            return service.searchTrainMonthly(enterpriseId, userId, beginDate, endDate, supplierId, customerId);
        } else {
            return service.searchTrainMonthly(enterpriseId, username, beginDate, endDate, supplierId, customerId);
        }
    }

    /**
     * 退票月报（根据退票单）
     */
    @RequestMapping("/order/refund/monthly")
    public List<FlightRefundOrder> searchMonthlyRefundOrder(HttpServletRequest request,
                                                            @RequestParam("beginDate") Date beginDate,
                                                            @RequestParam("endDate") Date endDate,
                                                            @RequestParam(value = "supplierId", defaultValue = "0") int supplierId
    ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        return service.searchMonthlyRefundOrder(enterpriseId, userId, beginDate, endDate, supplierId);
    }

    /**
     * 统计月报
     */
    @RequestMapping("/statistic/monthly")
    public List<ReportStatisticDto> statFlightMonthSale(HttpServletRequest request,
                                                        @RequestParam("beginDate")
                                                        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)  LocalDate beginDate,
                                                        @RequestParam("endDate")
                                                        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        return service.statMonthSale(getEnterpriseId(request), getUserId(request), beginDate, endDate);
    }

    /**
     * 统计日报
     */
    @RequestMapping("/statistic/daily")
    public List<ReportStatisticDto> statDailySaleStat(HttpServletRequest request,
        @RequestParam("beginDate")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)  LocalDate beginDate,
        @RequestParam("endDate")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        return service.statDailySale(getEnterpriseId(request), getUserId(request), beginDate, endDate);
    }

    /**
     * 支付方式统计
     * @param dateType 0 - 账单日期 1-审核日期
     */
    @RequestMapping("/paymentMethod/statistic")
    public List<ReportStatisticDto> statAmountByPaymentMethod(HttpServletRequest request,
                                                                  @RequestParam(value = "dateType", defaultValue = "0") final int dateType,
                                                                  @RequestParam("beginDate") Date beginDate,
                                                                  @RequestParam("endDate") Date endDate
    ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        return service.statAmountByPaymentMethod(enterpriseId, userId, dateType, beginDate, endDate);
    }

    /**
     * 支付方式统计(下载）
     * @param dateType 0 - 账单日期 1-审核日期
     */
    @RequestMapping("/paymentMethod/statistic/download")
    public void downloadStatAmountByPaymentMethod(HttpServletRequest request,
                                                  HttpServletResponse response,
                                                              @RequestParam(value = "dateType", defaultValue = "0") final int dateType,
                                                              @RequestParam("beginDate") Date beginDate,
                                                              @RequestParam("endDate") Date endDate
    ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        List<ReportStatisticDto> list = service.statAmountByPaymentMethod(enterpriseId, userId, dateType, beginDate, endDate);

        //输出
        PrintWriter out;
        try {
            String filename = "stat-payment-method-" + DateUtil.formatDate(DateUtil.getCurDateTime(), "yyyyMMddHHmmss") + ".csv";
            response.setHeader("Content-Disposition", "inline; filename=" + filename);
            response.setContentType("application/octet-stream");

            // 加上UTF-8文件的标识字符
            response.getOutputStream().write(
                    new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8));

            StringBuilder sb = new StringBuilder();
            sb.append(",").append("支付方式,").append(",").append("数量,").append("总金额,")
                    .append("总成本,").append("未付成本,").append("总利润,").append("\r");
            out.print(sb);

            int index = 0;
            for (ReportStatisticDto dto : list) {
                index++;
                String name = dto.getPayMethod() == null ? "": dto.getPayMethod().getName();

                sb = ReportStatisticDto.exportContent(index, name, dto);
                out.print(sb);
            }
            out.flush();

            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 供应商统计
     * @param dateType 日期类型
     *                 0 - 账单日期
     *                 1 - 审核日期
     */
    @RequestMapping("/supplier/statistic")
    public List<ReportStatisticDto> statAmountBySupplier(HttpServletRequest request,
                                                                  @RequestParam(value = "dateType", defaultValue = "0") final int dateType,
                                                                  @RequestParam("beginDate") Date beginDate,
                                                                  @RequestParam("endDate") Date endDate) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        return service.statAmountBySupplier(enterpriseId, userId, dateType, beginDate, endDate);
    }

    /**
     * 供应商统计(download)
     * @param dateType 日期类型
     *                 0 - 账单日期
     *                 1 - 审核日期
     */
    @RequestMapping("/supplier/statistic/download")
    public void downloadStatAmountBySupplier(HttpServletRequest request,
                                                         HttpServletResponse response,
                                                         @RequestParam(value = "dateType", defaultValue = "0") final int dateType,
                                                         @RequestParam("beginDate") Date beginDate,
                                                         @RequestParam("endDate") Date endDate) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        List<ReportStatisticDto> list = service.statAmountBySupplier(enterpriseId, userId, dateType, beginDate, endDate);

        //输出
        PrintWriter out;
        try {
            String filename = "stat-supplier-" + DateUtil.formatDate(DateUtil.getCurDateTime(), "yyyyMMddHHmmss") + ".csv";
            response.setHeader("Content-Disposition", "inline; filename=" + filename);
            response.setContentType("application/octet-stream");

            // 加上UTF-8文件的标识字符
            response.getOutputStream().write(
                    new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8));

            StringBuilder sb = new StringBuilder();
            sb.append(",").append("供应商,").append(",").append("数量,").append("总金额,")
                    .append("总成本,").append("未付成本,").append("总利润,").append("\r");
            out.print(sb);

            int index = 0;
            for (ReportStatisticDto dto : list) {
                index++;
                String supplierName = dto.getSupplier() == null ? "": dto.getSupplier().getName();

                sb = ReportStatisticDto.exportContent(index, supplierName, dto);
                out.print(sb);
            }
            out.flush();

            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 预订员(客服）销售统计
     */
    @RequestMapping("/statistic/op1")
    public List<ReportStatisticDto> statFlightMonthSaleByOp1(HttpServletRequest request,
                                                        @RequestParam("beginDate") Date beginDate,
                                                        @RequestParam("endDate") Date endDate
    ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);

        return service.statFlightMonthSaleByOp1(enterpriseId, userId, beginDate, endDate);
    }

    /**
     * 出票员统计
     */
    @RequestMapping("/statistic/op2")
    public List<ReportStatisticDto> statFlightMonthSaleByOp2(HttpServletRequest request,
                                                             @RequestParam("beginDate") Date beginDate,
                                                             @RequestParam("endDate") Date endDate
    ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);
        return service.statFlightMonthSaleByOp2(enterpriseId, userId, beginDate, endDate);
    }

    /**
     * 销售员统计
     */
    @RequestMapping("/statistic/salesman")
    public List<ReportStatisticDto> statMonthSaleBySalesman(HttpServletRequest request,
                                                             @RequestParam("beginDate") Date beginDate,
                                                             @RequestParam("endDate") Date endDate
    ) {
        final int enterpriseId = getEnterpriseId(request);
        final int userId = getUserId(request);

        return service.statMonthSaleBySalesman(enterpriseId, userId, beginDate, endDate);
    }

    /**
     * 航空公司统计
     */
    @RequestMapping("/statistic/airlines")
    public List<ReportStatisticDto> statMonthSaleByAirlines(HttpServletRequest request,
                                                            @RequestParam("beginDate") Date beginDate,
                                                            @RequestParam("endDate") Date endDate
    ) {
        final int enterpriseId = getEnterpriseId(request);
        return service.statMonthSaleByAirlines(enterpriseId, beginDate, endDate);
    }

}
